package com.lida.alipay.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayDataDataserviceBillDownloadurlQueryRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayDataDataserviceBillDownloadurlQueryResponse;
import com.google.gson.Gson;
import com.lida.alipay.pojo.vo.AlipayVo;
import com.lida.alipay.utils.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * author: lida
 * create time: 2021-03-02 21:40
 * description:
 */
@Slf4j
@RestController
@RequestMapping(value = "/alipay")
public class AlipayController extends PayBaseController {

    /**
     * 统一下单支付接口http://47.103.204.132:15000/alipay/pay
     **/
    @GetMapping("/pay")
    private void alipayPay(HttpServletResponse response) throws AlipayApiException, IOException {
        //这个应该是从前端端传过来的，这里为了测试就从后台写死了
        AlipayVo vo = new AlipayVo();
        vo.setOut_trade_no(UUID.randomUUID().toString().replace("-", ""));
        vo.setTotal_amount("100");
        vo.setSubject("nelson-test-title");
        vo.setProduct_code("FAST_INSTANT_TRADE_PAY");  //这个是固定的
        String json = new Gson().toJson(vo);
        log.info("json: {}", json);

        AlipayClient alipayClient = new DefaultAlipayClient(gateway_url, app_id, merchant_private_key, "json", charset, alipay_public_key, sign_type);
        // 设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(return_url);
        alipayRequest.setNotifyUrl(notify_url);
        alipayRequest.setBizContent(json);
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        log.info("result: {}", result);

        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write(result);
        response.getWriter().flush();
        response.getWriter().close();
        //return result;  //这里生成一个表单，会自动提交
    }

    /**
     * 支付宝服务器异步通知页面
     **/
    @PostMapping("/notify")
    public String alipayNotify(HttpServletRequest request, String out_trade_no, String trade_no, String trade_status) throws AlipayApiException {
        Map<String, String> params = getParamsMap(request);
        log.info("notify params: {}", JSONObject.toJSON(params));
        // 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, alipay_public_key, charset, sign_type);
        log.info("notify signVerified: {}", signVerified);
        if (signVerified) {
            //处理你的业务逻辑，更细订单状态等
            return ("success");
        } else {
            log.info("验证失败,不去更新状态");
            return ("fail");
        }
    }

    /**
     * 支付宝服务器同步通知页面
     * out_trade_no: 商户订单号
     * trade_no: 支付宝交易凭证号
     * total_amount: 交易状态
     **/
    @GetMapping("/return")
    public String alipayReturn(HttpServletRequest request, String out_trade_no, String trade_no, String total_amount) throws AlipayApiException {
        Map<String, String> params = getParamsMap(request);
        log.info("return params: {}", JSONObject.toJSON(params));

        // 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, alipay_public_key, charset, sign_type);
        log.info("return signVerified: {}", signVerified);

        if (signVerified) {
            return ("success");
        } else {
            log.info("验证失败,不去更新状态");
            return ("fail");
        }
    }

    /**
     * 支付宝对账
     **/
    @GetMapping("/alipayBill")
    public void alipayBill() throws Exception {
        log.info("向支付宝发起对账请求...");
        this.downBill();
    }

    private Map<String, String> getParamsMap(HttpServletRequest request) {
        Map<String, String> params = new HashMap<>();
        Map requestParams = request.getParameterMap();
        for (Object o : requestParams.keySet()) {
            String name = (String) o;
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用
            valueStr = new String(valueStr.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
            params.put(name, valueStr);
        }
        return params;
    }

    //@Scheduled(cron = "0 14 14 ? * *")
    private void downBill() throws Exception {
        //将订单提交至支付宝
        AlipayClient alipayClient = new DefaultAlipayClient(gateway_url, app_id,
                merchant_private_key, "json", charset,
                alipay_public_key,sign_type);
        AlipayDataDataserviceBillDownloadurlQueryRequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest();
        JSONObject json = new JSONObject();
        json.put("bill_type", "trade");
        //昨天的数据
        json.put("bill_date", "2021-02");
        request.setBizContent(json.toString());
        AlipayDataDataserviceBillDownloadurlQueryResponse response = alipayClient
                .execute(request);
        if (response.isSuccess()) {
            //获取下载地址 url
            String url = response.getBillDownloadUrl();
            //设置下载后生成 zip目录
            String filePath = file_path;
            String newZip = filePath + new Date().getTime() + ".zip";
            //开始下载
            FileUtil.downloadNet(url, newZip);
            //解压到指定目录
            FileUtil.unZip(newZip, file_zip_path);
        } else {
            //如果账单不存在， 插入一条空数据到数据库
            System.out.println("账单不存在");
        }

        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
        }
        System.out.println(JSON.toJSONString(response));
    }

}
